﻿#include <iostream>
#include <boost/asio.hpp>

using namespace boost::asio::ip;
using namespace std;

const int MAX_LENGTH = 1024; //最大长度,发送接收长度规定为1024
#define MAX_LENGTH  1024*2
#define HEAD_LENGTH 2

//int main()
//{
//	try
//	{
//		// 创建上下文服务
//		boost::asio::io_context ioc;
//		// 构建endpoint
//		tcp::endpoint remote_ep(address::from_string("127.0.0.1"), 10086);
//		// 创建socket
//		tcp::socket sock(ioc);
//		// 创建错误码.赋予初始值
//		boost::system::error_code error = boost::asio::error::host_not_found;
//		// connect
//		sock.connect(remote_ep, error);
//		if (error)
//		{
//			cout << "connect failed, code is " << error.value() << " error msg is" << error.message() << endl;
//			return 0;
//		}
//		// 连接成功,提示客户端发送消息
//		cout << "Enter message: ";
//		char request[MAX_LENGTH];
//		cin.getline(request, MAX_LENGTH);
//		size_t request_length = strlen(request);
//		boost::asio::write(sock, boost::asio::buffer(request, request_length));
//		// 接收服务端的数据
//		char reply[MAX_LENGTH];
//		size_t reply_length = boost::asio::read(sock, boost::asio::buffer(reply, request_length));
//		//当前形式其实是:发多少给服务器,就传多少数据回给客户端,这个策略其实非常幼稚,这种情况几乎不太现实
//		//使用read_some其实可以解决这个问题,但与此同时TCP黏包和拆包的问题没有解决,所以数据其实不一定正确的
//		//当前先这么写
//		cout << "Reply is: ";
//		cout.write(reply, reply_length);
//		cout << endl;
//	}
//	catch (std::exception& e)
//	{
//		cerr << "Exception: " << e.what() << endl;
//	}
//	return 0;
//}

int main()
{
    try {
        //创建上下文服务
        boost::asio::io_context ioc;
        //构造endpoint
        tcp::endpoint remote_ep(address::from_string("127.0.0.1"), 10086);
        tcp::socket sock(ioc);
        boost::system::error_code error = boost::asio::error::host_not_found; ;
        sock.connect(remote_ep, error);
        if (error)
        {
            cout << "connect failed, code is " << error.value() << " error msg is " << error.message();
            return 0;
        }

        //send
        std::cout << "Enter message: ";
        char request[MAX_LENGTH];
        std::cin.getline(request, MAX_LENGTH);
        size_t request_length = strlen(request);
        char send_data[MAX_LENGTH] = { 0 };
        memcpy(send_data, &request_length, 2);
        memcpy(send_data + 2, request, request_length);
        boost::asio::write(sock, boost::asio::buffer(send_data, request_length + 2));

        //read
        char reply_head[HEAD_LENGTH];
        size_t reply_length = boost::asio::read(sock, boost::asio::buffer(reply_head, HEAD_LENGTH));
        short msglen = 0;
        memcpy(&msglen, reply_head, HEAD_LENGTH);
        char msg[MAX_LENGTH] = { 0 };
        size_t  msg_length = boost::asio::read(sock, boost::asio::buffer(msg, msglen));
        std::cout << "Reply is: ";
        std::cout.write(msg, msglen) << endl;
        std::cout << "Reply len is " << msglen;
        std::cout << "\n";
    }
    catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << endl;
    }
    return 0;
}